package com.googlecode.sparda.commons.io.stream.policy;

import java.io.OutputStream;
import java.util.concurrent.LinkedBlockingDeque;

import com.googlecode.sparda.commons.io.stream.ManagedOutputStream;

/**
 * An {@link AstractComplexCMOSPolicy} is a skeleton class to build a policy based on 
 * opened stream and on born date stream.
 * @author Fabio Grucci (<i>alias</i> <b>Phoenix</b>)
 *
 */
public abstract class AstractComplexCMOSPolicy implements ClosingManagedOutputStreamPolicy {

	protected final LinkedBlockingDeque<ManagedOutputStream<? extends OutputStream>> bornStream;
	
	protected final LinkedBlockingDeque<ManagedOutputStream<? extends OutputStream>> openedStream;
	
	public AstractComplexCMOSPolicy() {
		this.openedStream = new LinkedBlockingDeque<ManagedOutputStream<? extends OutputStream>>();
		this.bornStream = new LinkedBlockingDeque<ManagedOutputStream<? extends OutputStream>>();
	}
	
	@Override
	public void notifyDefinitelyClosed(ManagedOutputStream<? extends OutputStream> closedStream) {
		this.openedStream.remove(closedStream);
		this.bornStream.remove(closedStream);
	}

	@Override
	public void notifyNewManagedOutputStream(ManagedOutputStream<? extends OutputStream> newStream) {
		this.bornStream.add(newStream);
		this.notifyOpen(newStream);
	}

	@Override
	public void notifyOpen(ManagedOutputStream<? extends OutputStream> openedStream) {
		this.openedStream.add(openedStream);
	}

	@Override
	public void notifyTemporaryClosed(ManagedOutputStream<? extends OutputStream> temporaryClosedStream) {
		this.openedStream.remove(temporaryClosedStream);
	}
	
}
